package com.mkh.st.common.log.logback.dingtalk;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.spi.ThrowableProxy;
import ch.qos.logback.core.AppenderBase;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.exception.ExceptionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import static org.apache.logging.log4j.util.Chars.LF;

/**
 * Author: xhx
 * Date: 2021/10/15 8:15 下午
 * FileName: DingTalkAppender
 * Description:
 */
public class DingTalkAppender extends AppenderBase<LoggingEvent> {

	PatternLayoutEncoder encoder;

	DingTalkParam dingTalkParam;

	@Override
	public void start() {
		//可以做一些初始化相关资源的操作，如数据库连接，redis线程池等等
		if (this.encoder == null) {
			//name ： logback.xml 中 appender 标签 配置的name值
			addError("No encoder set for the appender named [" + name + "].");
			return;
		}
		super.start();
	}

	@Override
	public void stop() {
		//可以做一些释放相关资源的操作，如数据库连接，redis线程池等等
//		System.out.println("stop方法被调用");
		if (!isStarted()) {
			return;
		}
		super.stop();
	}

	@Override
	protected void append(LoggingEvent event) {

//		System.out.println("-LoggingEvent------------>" + event.getMessage());
		/**
		 * 指定只有 error 级别的日志，才发消息
		 * 后续可以根据配置指定，此处暂不实现
		 */
		if (dingTalkParam == null) {
			return;
		}

		boolean sendMsg = dingTalkParam.getSendMsg();
		if (!sendMsg) {
			addInfo("不输出日志===================");
			return;
		}

		Level level = event.getLevel();
		if (Level.ERROR.levelInt == level.levelInt) {
			String accessToken = dingTalkParam.getWebHookAccessToken();
			if (StrUtil.isEmpty(accessToken)) {
//				System.out.println("没有匹配的name和token");
				addError("No dingTalk accessToken for the appender named [" + name + "].");
				return;
			}

			String message = event.getMessage();
			if (StrUtil.isNotEmpty(dingTalkParam.getMarkMsg())) {

				StringBuilder content = new StringBuilder(8192);

				content.append("错误日志").append(LF)
						.append("级别：").append(event.getLevel()).append(LF)
						.append("位置：").append(event.getLoggerName()).append(LF)
						.append("信息：").append(event.getMessage());

				ThrowableProxy tp = (ThrowableProxy) event.getThrowableProxy();
				if (tp != null) {
					// 存在异常信息
					String stackTrace = ExceptionUtils.getStackTrace(tp.getThrowable());
					content.append(LF).append("异常：").append(stackTrace);
				}
				message = content.toString();
			}
			List<String> atMobiles = new ArrayList<>();
			if (StrUtil.isNotEmpty(dingTalkParam.getAtMobiles())){
				String[] mobileArr = StrUtil.split(dingTalkParam.getAtMobiles(), ",");
				atMobiles = Arrays.asList(mobileArr);
			}
			// 发钉钉报警消息
			DingTalkHelper.sendTextMsg(message,accessToken, dingTalkParam.getMarkMsg(), atMobiles);

		}

	}

	public PatternLayoutEncoder getEncoder() {
		return encoder;
	}

	public void setEncoder(PatternLayoutEncoder encoder) {
		this.encoder = encoder;
	}

	public DingTalkParam getDingTalkParam() {
		return dingTalkParam;
	}

	public void setDingTalkParam(DingTalkParam dingTalkParam) {
		this.dingTalkParam = dingTalkParam;
	}
}
